package Model.xml.protocols;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthConsumer;
import oauth.signpost.basic.DefaultOAuthProvider;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;

/**
 *
 * @author pieterc
 */
public class Twitter implements Protocol, Serializable {

    public static final int charLimit = 140;
    private ProtocolXML xml = new TwitterXML();
    private OAuthConsumer consumer;
    private int access = Protocol.READONLY;
    private String pinCode = null;
    private Object info;
    private OAuthProvider provider;

    public Twitter() {
        init();
    }

    private void init() {
        try {
            consumer = new DefaultOAuthConsumer("HL7nILRYkAXZ5RCz877g", "ZPOVe4mHi2YvBmEQw4AjA8pBCMrsCl0EtxIM8ZuCg");
            provider = new DefaultOAuthProvider("http://twitter.com/oauth/request_token", "http://twitter.com/oauth/access_token", "http://twitter.com/oauth/authorize");
            info = provider.retrieveRequestToken(consumer, OAuth.OUT_OF_BAND);
        } catch (Exception e) {
            System.out.println("error: " + e);
        }
    }

    public Twitter(int access) {
        this.access = access;
        init();
    }

    public void authenticate() {
        try {
            String token, tokenSec;
            provider.retrieveAccessToken(consumer, pinCode);
            token = consumer.getToken();
            tokenSec = consumer.getTokenSecret();
            consumer.setTokenWithSecret(token, tokenSec);
        } catch (Exception ex) {
            System.out.println("Authentication failed: " + ex.getMessage());
        }
    }

    public String getApiURL() {
        return "http://api.twitter.com/1/";
    }

    public String getApiName() {
        return "twitter.com";
    }

    public ProtocolXML getXMLHandler() {
        return xml;
    }

    public void loadStandardTimeline() {
        try {
            // create a request that requires authentication
            URL url = new URL("http://api.twitter.com/1/statuses/home_timeline.xml");
            HttpURLConnection request = (HttpURLConnection) url.openConnection();
            consumer.sign(request);
            request.connect();
            int statusCode = request.getResponseCode();
            String s = getApiName() + ".xml";
            File f = new File(s);
            if (!f.exists()) {
                f.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream(s);
            java.io.BufferedOutputStream bout = new BufferedOutputStream(fos, 1024);
            InputStream in = request.getInputStream();
            byte[] data = new byte[1024];
            int x = 0;
            while ((x = in.read(data, 0, 1024)) >= 0) {
                bout.write(data, 0, x);
            }
            bout.close();
            in.close();
        } catch (IOException ex) {
            Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);
        } catch (OAuthMessageSignerException ex) {
            Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);
        } catch (OAuthExpectationFailedException ex) {
            Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);
        } catch (OAuthCommunicationException ex) {
            Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void postStatus(String message) {
        if (message.length() < charLimit) {
            try {
                URL url = new URL("http://api.twitter.com/1/statuses/update.xml");
                HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
                urlc.setRequestMethod("POST");
                consumer.sign(urlc);
                urlc.setDoOutput(true);
                urlc.setDoInput(true);
                urlc.setUseCaches(false);
                urlc.setAllowUserInteraction(false);
                urlc.setRequestProperty("Content-type", "text/xml; charset=" + "UTF-8");

                OutputStream out = urlc.getOutputStream();
                Writer writer = new OutputStreamWriter(out, "UTF-8");
                writer.write("<status>" + message + "</status>");
                writer.close();

                InputStream in = urlc.getInputStream();
                Scanner sc = new Scanner(in);
                while (sc.hasNext()) {
                    System.out.println(sc.next());
                }
                sc.close();
                in.close();
            } catch (OAuthMessageSignerException ex) {
                Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);
            } catch (OAuthExpectationFailedException ex) {
                Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);
            } catch (OAuthCommunicationException ex) {
                Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public int getAccess() {
        return access;
    }

    public int getAuthenticationMethod() {
        return OAUTH;
    }

    public void setCredentials(Object... o) {
        pinCode = (String) o[0];
        authenticate();
    }

    public Object getInfo() {
        return info;
    }
}
